//package net.tavion.angelboot.common.aop;
//
//import com.alibaba.fastjson.JSON;
//import net.tavion.angelboot.common.enums.RequestHeaderElement;
//import net.tavion.angelboot.common.exception.AngelException;
//import net.tavion.angelboot.common.head.RequestHeadDataHolder;
//import net.tavion.angelboot.common.utils.DateTimeUtils;
//import net.tavion.angelboot.common.utils.GenerateIdUtils;
//import net.tavion.angelboot.common.utils.WebFluxUtils;
//import net.tavion.angelboot.common.vo.GenericResponse;
//import net.tavion.angelboot.framework.logger.MDCUtil;
//import org.aspectj.lang.ProceedingJoinPoint;
//import org.aspectj.lang.annotation.Around;
//import org.aspectj.lang.annotation.Aspect;
//import org.aspectj.lang.annotation.Pointcut;
//import org.slf4j.Logger;
//import org.slf4j.LoggerFactory;
//import org.springframework.context.annotation.Configuration;
//import org.springframework.core.Ordered;
//import org.springframework.core.annotation.Order;
//import org.springframework.security.access.AccessDeniedException;
//import reactor.core.publisher.Mono;
//import java.time.Instant;
//import java.util.Optional;
//import java.util.stream.Collectors;
//import java.util.stream.Stream;
//
///**
// * @author yuzhou
// * @date 2017/6/28/
// * @time 5:11:27
// *
// */
//@Aspect
//@Configuration
//@Order(value=Ordered.HIGHEST_PRECEDENCE + 10)
//public class ControllerAspect {
//    private static final Logger logger = LoggerFactory.getLogger(ControllerAspect.class);
//
////    @Resource
////    private IRequestHistoryService requestHistoryService;
//
//    @Pointcut("execution (* net.tavion.angelboot.*..*Controller.*(..))")
//    public void anyAngelControllerMethod() {
//    }
//
//    @Pointcut("@within(org.springframework.web.bind.annotation.RestController)")
//    public void anyRestControllerMethod() {
//    }
//
//    @Around("anyAngelControllerMethod()||anyRestControllerMethod()")
//    public Object doAroundController(ProceedingJoinPoint pjp) throws Throwable {
//
//        WebFluxUtils.getServerHttpRequest().flatMap(
//              request -> {
//                  MDCUtil.putMDCKey(Optional.ofNullable(request.getHeaders().getFirst(RequestHeaderElement.requestId.getName())).orElse(GenerateIdUtils.generateRequestId()));
//                  RequestHeadDataHolder.getRequestHeadData().setLanguage(request.getHeaders().getFirst(RequestHeaderElement.language.getName()));
//                  RequestHeadDataHolder.getRequestHeadData().setChannel(request.getHeaders().getFirst(RequestHeaderElement.channelKey.getName()));
//                  RequestHeadDataHolder.getRequestHeadData().setUserId(request.getHeaders().getFirst(RequestHeaderElement.userId.getName()));
//                  return null;
//              }
//        );
//
//        String lan=WebFluxUtils.getHeader(RequestHeaderElement.language.getName()).toString();
//
//
//        Instant startInstant = Instant.now();
//        Object responseObject = null;
//
////        RequestHistory requestHistory = new RequestHistory();
//       // String status = SystemConstant.SUCCESS;
//        try {
//
//            this.logRequest(pjp);
//            responseObject = pjp.proceed();
//        } catch (AccessDeniedException e) {
//            // throw spring security handle
//            throw e;
//        } catch (AngelException e){
//            responseObject = new GenericResponse<>(e.getErrorCode(),e.getMessage());
//        } catch (Exception e) {
//            logger.error("the system handle fail", e);
//            responseObject = new GenericResponse<>(e.getMessage());
//        } finally {
//            long execTm = DateTimeUtils.durationMillis(startInstant, Instant.now());
//
//            this.logResponse(responseObject, execTm);
//            RequestHeadDataHolder.clear();
//            MDCUtil.removeMDCKey();
//        }
//        return responseObject;
//    }
//
//    private void logRequest(ProceedingJoinPoint pjp) {
//        if (logger.isInfoEnabled()) {
//            try {
//              //  HttpServletRequest httpRequest = WebUtils.getHttpServletRequest();
//                String data = Optional.ofNullable(pjp.getArgs()).map(args -> Stream.of(args).map(this::toJsonString).collect(Collectors.joining("~"))).orElse("");
//               // requestHistory.setRequest(data);
//
//
//
//               Mono<String> path= WebFluxUtils.getServerHttpRequest().flatMap(
//                        request -> Mono.justOrEmpty(request.getPath().contextPath().value())
//                );
//
//
//                logger.info("{\"action\":\"request\",\"uri\":\"{}\",\"data\":{}}", path, data);
//            } catch (Exception t) {
//                logger.error("log request fail", t);
//            }
//        }
//    }
//
//    private void logResponse(Object result, long execTm) {
//        if (logger.isInfoEnabled()) {
//            try {
//                String data =  Optional.ofNullable(result).map(this::toJsonString).orElse(null);
//
//                WebFluxUtils.getServerHttpRequest().flatMap(
//                        request -> {
//
//                        }
//                ).doOnSuccess();
//
//
//
//               // requestHistory.setResponse(data);
//                logger.info("{\"action\":\"response\",\"execTm\":\"{}\",\"data\":{}}", execTm, data);
//            } catch (Exception t) {
//                logger.error("log response fail", t);
//            }
//        }
//    }
//
//    private String toJsonString(Object object) {
//        if (null == object) {
//            return null;
//        }
//        try {
//            return JSON.toJSONString(object);
//        } catch (Exception e) {
//            logger.warn("Print Json Object fail!");
//            return null;
//        }
//    }
//}
